/////////////////////////////////////////////////////////////////////////////////////
// Header Protection
#ifndef _LIST_H_
#define _LIST_H_

/////////////////////////////////////////////////////////////////////////////////////
// Include Files
#include <assert.h>

/////////////////////////////////////////////////////////////////////////////////////
// A list class which contains a variable length array of the templated type. The 
//     assignment operator is called on each element during copy operations, making 
//     this class slow, but safe. If your templated type does not contain dynamic 
//     memory, you should use the faster 'flist_t' instead.
// element_t: template - the type of data to store in each element of the list
template< typename element_t >
class list_t
{
public:     // accessors
	uint_t GetSize() const { return m_uSize; }

public:     // methods

	// A constructor which creates an empty list.
	list_t() : m_pData(CE_NULL), m_uSize(0), m_uCapacity(0) { }

	// A constructor which creates a list with the given capacity.
	// _uCapacity: uint_t - the starting capacity of the list
	explicit list_t( uint_t _uCapacity );

	// A constructor which creates a list by copying an array.
	// _pData: element_t * - data which the list will copy
	// _uCount: uint_t     - the amount of data to copy
	list_t( element_t *_pData, uint_t _uCount );

	// A constructor which creates a list as a copy of another list.
	// _rList (list_t const &) - a list to copy
	list_t( list_t const & _rList );

	// Destructor.
	~list_t() { if(m_pData) delete[] m_pData; }

	// Appends an item to the end of the list.
	// _rElement: element_t & - the item to append to the end of the list
	void Append( element_t & _rElement );

	// Set the capacity of the list. If the new capacity is less than the current 
	//     size, the excess elements will be truncated.
	// _uCapacity: uint_t - the new capacity of the list
	void SetCapacity( uint_t _uCapacity );

	// Clears the list.
	void Clear();

public:     // operators

	// Makes this list a copy of the given list.
	// _rList: list_t const & - the list to copy
	// return: list_t & - this list
	list_t & operator =( list_t const & _rList );

	// Accesses the given element of the list.
	// _iIndex: int_t - the index to access
	// return: element_t & - the data at the given index
	inline element_t & operator []( uint_t _uIndex )
	{
		assert( _uIndex < m_uSize );
		return m_pData[_uIndex];
	}

	inline element_t const & operator []( uint_t _uIndex ) const
	{
		assert( _uIndex < m_uSize );
		return m_pData[_uIndex];
	}

private:    // data
	element_t * m_pData;
	uint_t      m_uSize;
	uint_t      m_uCapacity;
};

/////////////////////////////////////////////////////////////////////////////////////
// An alternative to 'list_t' which uses memcpy for copy operations, making this 
//     version faster but unsafe if the templated type contains dynamic memory.
// element_t: template - the type of data to store in each element of the list
template< typename element_t >
class flist_t
{
public:     // accessors
	uint_t GetSize() const { return m_uSize; }

public:     // methods

	// A constructor which creates an empty list.
	flist_t() : m_pData(CE_NULL), m_uSize(0), m_uCapacity(0) { }

	// A constructor which creates a list with the given capacity.
	// _uCapacity: uint_t - the starting capacity of the list
	explicit flist_t( uint_t _uCapacity );

	// A constructor which creates a list by copying an array.
	// _pData: element_t * - data which the list will copy
	// _uCount: uint_t     - the amount of data to copy
	flist_t( element_t * _pData, uint_t _uCount );

	// A constructor which creates a list as a copy of another list.
	// _rList (list_t const &) - a list to copy
	flist_t( flist_t const & _rList );

	// Destructor.
	~flist_t() { if(m_pData) delete[] m_pData; }

	// Appends an item to the end of the list.
	// _rElement: element_t & - the item to append to the end of the list
	void Append( element_t & _rElement );

	// Set the capacity of the list. If the new capacity is less than the current 
	//     size, the excess elements will be truncated.
	// _uCapacity: uint_t - the new capacity of the list
	void SetCapacity( uint_t _uCapacity );

	// Clears the list.
	void Clear();

public:     // operators

	// Makes this list a copy of the given list.
	// _rList: list_t const & - the list to copy
	// return: list_t & - this list
	flist_t & operator =( flist_t const & _rList );

	// Accesses the given element of the list.
	// _uIndex: uint_t - the index to access
	// return: element_t & - the data at the given index
	inline element_t & operator []( uint_t _uIndex )
	{
		assert( _uIndex < m_uSize );
		return m_pData[_uIndex];
	}

	inline element_t const & operator []( uint_t _uIndex ) const
	{
		assert( _uIndex < m_uSize );
		return m_pData[_uIndex];
	}

private:    // data
	element_t *m_pData;
	uint_t     m_uSize;
	uint_t     m_uCapacity;
};

/////////////////////////////////////////////////////////////////////////////////////
// Template Implementation
#include "Types\List.hpp"

/////////////////////////////////////////////////////////////////////////////////////
// Header Protection
#endif // _LIST_H_
